#ifndef __LOG_H__
#define __LOG_H__

#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <stdarg.h>
#include <time.h>

/// 全局文件日志回调最大数量
#define LOG_CB_FUNC_ARR_LEN 16
/// 自定义文件日志命名长度
#define LOG_TAG_LEN 32
/// 标准输出使用颜色
#define LOG_COLOR 1
    enum
    {
        LOG_FILE_UNLOCK = 0,
        LOG_FILE_LOCK,
    };
    enum
    {
        LOG_LEVEL_DEBUG = 0,
        LOG_LEVEL_INFO,
        LOG_LEVEL_WARNING,
        LOG_LEVEL_ERROR,
        LOG_LEVEL_FATAL,
    };
    extern const char *log_level_str(int level);
    extern int log_str_level(const char *str);
    extern void log_log(int level, const char *file, int line, const char *fmt, ...);

    typedef void (*log_lock_impl)(int lock, FILE *fp);
    extern void log_set_lock(log_lock_impl func);
    extern int log_add_fp(FILE *fp, const char *tag);
    extern int log_add_fp2(FILE *fp, const char *tag, int lowlevel);
    extern int log_upt_fp(FILE *fp, const char *tag);
    extern int log_upt_fp2(FILE *fp, const char *tag, int lowlevel);
    extern int log_flog(const char *tag, int level, const char *file, int line, const char *fmt, ...);

    extern int log2_log(const char *tag, int level, const char *file, int line, const char *fmt, ...);

#define log_debug(...) log_log(LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_info(...) log_log(LOG_LEVEL_INFO, __FILE__, __LINE__, __VA_ARGS__)
#define log_warning(...) log_log(LOG_LEVEL_WARNING, __FILE__, __LINE__, __VA_ARGS__)
#define log_error(...) log_log(LOG_LEVEL_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define log_fatal(...) log_log(LOG_LEVEL_FATAL, __FILE__, __LINE__, __VA_ARGS__)

#define log_f_debug(tag, ...) log_flog(tag, LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_f_info(tag, ...) log_flog(tag, LOG_LEVEL_INFO, __FILE__, __LINE__, __VA_ARGS__)
#define log_f_warning(tag, ...) log_flog(tag, LOG_LEVEL_WARNING, __FILE__, __LINE__, __VA_ARGS__)
#define log_f_error(tag, ...) log_flog(tag, LOG_LEVEL_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define log_f_fatal(tag, ...) log_flog(tag, LOG_LEVEL_FATAL, __FILE__, __LINE__, __VA_ARGS__)

#define log2_debug(tag, ...) log2_log(tag, LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log2_info(tag, ...) log2_log(tag, LOG_LEVEL_INFO, __FILE__, __LINE__, __VA_ARGS__)
#define log2_warning(tag, ...) log2_log(tag, LOG_LEVEL_WARNING, __FILE__, __LINE__, __VA_ARGS__)
#define log2_error(tag, ...) log2_log(tag, LOG_LEVEL_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define log2_fatal(tag, ...) log2_log(tag, LOG_LEVEL_FATAL, __FILE__, __LINE__, __VA_ARGS__)

#define log2_errorif(tag, s, err_str)                                            \
    do                                                                           \
    {                                                                            \
        if (s)                                                                   \
        {                                                                        \
            log2_error(tag, "%s: %s(code:%d)", err_str, strerror(errno), errno); \
        }                                                                        \
    } while (0);

#ifdef __cplusplus
}
#endif

#endif